package cn.tedu.work;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class WorkConsumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //设置连接信息
        ConnectionFactory cf = new ConnectionFactory();
        cf.setHost("192.168.144.160");
        cf.setUsername("guest");
        cf.setPassword("guest");
        //创建tcp连接
        Connection nc = cf.newConnection();
        Channel cc = nc.createChannel();
        //创建队列-生产者和消费者都要创建队列，为了避免找不到队列而报异常
        //队列有一个特点：如果该队列已经存在，忽略创建命令；如果队列不存在才会执行创建命令
        //队列另一个特点：队列一旦创建，属性不可改变
        cc.queueDeclare("task_queue",true,false,false,null);
        //消费数据
        /*
          第一个参数：队列名
          第二个参数：autoACK，先写成true
          第三个参数：deliverCallback，处理消息的回调函数
          第四个参数：cancelCallback，取消接收数据时的回调函数
         */
        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String s, Delivery delivery) throws IOException {
                //消息封装到了delivery对象中
                byte[] body = delivery.getBody();
                String msg = new String(body);
                //拿到消息后，我们进行处理，为了模拟耗时操作，设计遇到一个'.',就休息1s
                System.out.println("接收到消息："+msg);
                for (int i = 0; i < msg.length(); i++) {
                    if (msg.charAt(i)=='.'){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                System.out.println(msg+"处理完毕");
                //发送消息回执
                //第一个参数：消息确认，消息的标签
                //第二个参数：如果是true意味着，一个标签可以确切多条消息
                //第二个参数：如果是false意味着，一个标签只能确认一条消息
                cc.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
            }
        };
        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String s) throws IOException {

            }
        };
        //设置qos=1，消费者每次只抓取一条消息，在这条没处理完毕之前，是不允许接收下一条消息
        //qos只有在手动ack才有效，autoAck=false
        cc.basicQos(1);
        cc.basicConsume("task_queue",false,deliverCallback,cancelCallback);
    }
}
